﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;

using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Eqwww.Code
{
    public  class Common
    {
        public static string Guid()
        {
            return System.Guid.NewGuid().ToString();
        }


        /// <summary>
        /// 字符串如果操过指定长度则将超出的部分用指定字符串代替
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetSubString(string p_SrcString, int p_Length, string p_TailString)
        {
            return GetSubString(p_SrcString, 0, p_Length, p_TailString);
        }

        /// <summary>
        /// 取指定长度的字符串
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_StartIndex">起始位置</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString)
        {
            string myResult = p_SrcString;

            Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString);
            foreach (char c in Encoding.UTF8.GetChars(bComments))
            {    //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3)
                if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3'))
                {
                    //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
                    //当截取的起始位置超出字段串长度时
                    if (p_StartIndex >= p_SrcString.Length)
                        return "";
                    else
                        return p_SrcString.Substring(p_StartIndex,
                                                       ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length);
                }
            }

            if (p_Length >= 0)
            {
                byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString);

                //当字符串长度大于起始位置
                if (bsSrcString.Length > p_StartIndex)
                {
                    int p_EndIndex = bsSrcString.Length;

                    //当要截取的长度在字符串的有效长度范围内
                    if (bsSrcString.Length > (p_StartIndex + p_Length))
                    {
                        p_EndIndex = p_Length + p_StartIndex;
                    }
                    else
                    {   //当不在有效范围内时,只取到字符串的结尾

                        p_Length = bsSrcString.Length - p_StartIndex;
                        p_TailString = "";
                    }

                    int nRealLength = p_Length;
                    int[] anResultFlag = new int[p_Length];
                    byte[] bsResult = null;

                    int nFlag = 0;
                    for (int i = p_StartIndex; i < p_EndIndex; i++)
                    {
                        if (bsSrcString[i] > 127)
                        {
                            nFlag++;
                            if (nFlag == 3)
                                nFlag = 1;
                        }
                        else
                            nFlag = 0;

                        anResultFlag[i] = nFlag;
                    }

                    if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1))
                        nRealLength = p_Length + 1;

                    bsResult = new byte[nRealLength];

                    Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength);

                    myResult = Encoding.Default.GetString(bsResult);
                    myResult = myResult + p_TailString;
                }
            }

            return myResult;
        }


        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public static string GetTimeStamp(System.DateTime time, int length = 13)
        {
            long ts = ConvertDateTimeToInt(time);
            return ts.ToString().Substring(0, length);
        }
        /// <summary>  
        /// 将c# DateTime时间格式转换为Unix时间戳格式  
        /// </summary>  
        /// <param name="time">时间</param>  
        /// <returns>long</returns>  
        public static long ConvertDateTimeToInt(System.DateTime time)
        {
            var startTime = System.TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0), TimeZoneInfo.Local);
            //System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000调整为13位      
            return t;
        }
        /// <summary>        
        /// 时间戳转为C#格式时间        
        /// </summary>        
        /// <param name=”timeStamp”></param>        
        /// <returns></returns>        
        public static DateTime ConvertStringToDateTime(string timeStamp)
        {
            //DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            var dtStart = System.TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
            long lTime = long.Parse(timeStamp + "0000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }

        /// <summary>
        /// 时间戳转为C#格式时间10位
        /// </summary>
        /// <param name="timeStamp">Unix时间戳格式</param>
        /// <returns>C#格式时间</returns>
        public static DateTime GetDateTimeFrom1970Ticks(long curSeconds)
        {
            var dtStart = System.TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Local);
            //DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            return dtStart.AddSeconds(curSeconds);
        }

        /// <summary>
        /// 验证时间戳
        /// </summary>
        /// <param name="time"></param>
        /// <param name="interval">差值（分钟）</param>
        /// <returns></returns>
        public static bool IsTime(long time, double interval)
        {
            DateTime dt = GetDateTimeFrom1970Ticks(time);
            //取现在时间
            DateTime dt1 = DateTime.Now.AddMinutes(interval);
            DateTime dt2 = DateTime.Now.AddMinutes(interval * -1);
            if (dt > dt2 && dt < dt1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 判断时间戳是否正确（验证前8位）
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static bool IsTime(string time)
        {
            string str = GetTimeStamp(DateTime.Now, 8);
            if (str.Equals(time))
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public static string GetFileSizeStr(long b)
        {
            const int GB = 1024 * 1024 * 1024;
            const int MB = 1024 * 1024;
            const int KB = 1024;


            if (b / GB >= 1)
            {
                return Math.Round(b / (float)GB, 2) + "GB";
            }


            if (b / MB >= 1)
            {
                return Math.Round(b / (float)MB, 2) + "MB";
            }


            if (b / KB >= 1)
            {
                return Math.Round(b / (float)KB, 2) + "KB";
            }


            return b + "B";
        }

        public static ModelResult SuccessResult(string message = null)
        {
            return new ModelResult
            {
                state = "success",
                message = message == null ? "操作成功" : message
            };
        }

        public static ModelResult ErrorResult(string message = null)
        {
            return new ModelResult
            {
                state = "error",
                message = message == null ? "未知错误" : message
            };
        }

        public static ModelResult ModelStateErrorResult(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState)
        {
            var sb = new StringBuilder();
            sb.Append("模型验证错误。<br>若出现本提示则说明控制器模型绑定缺少了某些字段（具体以下面提示为准）,请修正：<br>");
            foreach (var item in modelState)
            {
                if (item.Value.Errors.Count() > 0)
                {
                    sb.Append(item.Key + ":");
                    foreach (var err in item.Value.Errors)
                    {
                        sb.Append(err.ErrorMessage + ".");
                    }
                    sb.Append("<br />");
                }
            }
            return ErrorResult(sb.ToString());
        }

        /// <summary>
        /// 匹配正则
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <returns></returns>
        public static string RegexStr(string str, string regstr)
        {
            Regex reg = new Regex(regstr, RegexOptions.IgnoreCase);
            if (reg.IsMatch(str))
            {
                Match m = reg.Match(str);
                return m.Value;
            }
            else
                return string.Empty;
        }

        /// <summary>
        /// 匹配正则中的指定部分
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <param name="matchstr"></param>
        /// <returns></returns>
        public static string RegexStr(string str, string regstr, string matchstr)
        {
            Regex reg = new Regex(regstr, RegexOptions.IgnoreCase);
            Match m = reg.Match(str);
            if (reg.IsMatch(str))
                return m.Groups[matchstr].Value;
            else
                return string.Empty;
        }

        /// <summary>
        /// 匹配正则中的列表
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <returns></returns>
        public static List<string> RegexStrList(string str, string regstr)
        {
            Regex reg = new Regex(regstr, RegexOptions.IgnoreCase);
            if (reg.IsMatch(str))
            {
                MatchCollection mc = reg.Matches(str);
                List<string> ls = new List<string>();
                foreach (Match m in mc)
                {
                    ls.Add(m.Value);
                }
                return ls;
            }
            else
                return new List<string>();
        }

        /// <summary>
        /// 匹配正则中的指定部分的列表
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <param name="matchstr"></param>
        /// <returns></returns>
        public static List<string> RegexStrList(string str, string regstr, string matchstr)
        {
            Regex reg = new Regex(regstr, RegexOptions.IgnoreCase);
            MatchCollection mc = reg.Matches(str);
            List<string> ls = new List<string>();
            if (reg.IsMatch(str))
            {
                foreach (Match m in mc)
                {
                    ls.Add(m.Groups[matchstr].ToString());
                }
            }
            return ls;
        }

        public static List<string> RegexStrList(string str, string regstr, string[] matchstrs, char splittag)
        {
            Regex reg = new Regex(regstr, RegexOptions.IgnoreCase);
            MatchCollection mc = reg.Matches(str);
            List<string> ls = new List<string>();
            if (reg.IsMatch(str))
            {

                foreach (Match m in mc)
                {
                    string s = string.Empty;
                    foreach (string matchstr in matchstrs)
                    {
                        s = s == string.Empty ? m.Groups[matchstr].ToString() : s + splittag.ToString() + m.Groups[matchstr].ToString();
                    }
                    ls.Add(s);
                }
            }
            return ls;

        }

        /// <summary>
        /// 匹配正则中的指定部分的列表,并过滤重复项(重复项只保留一个)
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <param name="matchstr"></param>
        /// <returns></returns>
        public static List<string> RegStrListAndGuoLv(string str, string regstr, string matchstr)
        {
            List<string> ss = RegexStrList(str, regstr, matchstr);
            List<string> ss1 = new List<string>();
            for (int i = 0; i < ss.Count; i++)
            {
                if (ss1.IndexOf(ss[i]) < 0)
                    ss1.Add(ss[i]);
            }

            return ss1;
        }

        /// <summary>
        /// 替换指定正则部分regstr为nowstr
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <param name="nowstr"></param>
        /// <returns></returns>
        public static string ReplaceStr(string str, string regstr, string nowstr)
        {
            string s = Regex.Replace(str, regstr, nowstr);
            return s;
        }

        /// <summary>
        /// 替换指定正则部分regstr为空
        /// </summary>
        /// <param name="str"></param>
        /// <param name="regstr"></param>
        /// <returns></returns>
        public static string ReplaceStr(string str, string regstr)
        {
            return ReplaceStr(str, regstr, string.Empty);
        }

        public static string GetSpellCode(string CnStr)
        {

            string strTemp = "";

            int iLen = CnStr.Length;

            int i = 0;

            for (i = 0; i <= iLen - 1; i++)
            {

                strTemp += GetCharSpellCode(CnStr.Substring(i, 1));

            }

            return strTemp;

        }

        /// <summary>
        /// 得到一个汉字的拼音第一个字母，如果是一个英文字母则直接返回大写字母
        /// </summary>
        /// <param name="CnChar">单个汉字</param>
        /// <returns>单个大写字母</returns>

        private static string GetCharSpellCode(string CnChar)
        {

            long iCnChar;

            byte[] ZW = System.Text.Encoding.Default.GetBytes(CnChar);

            //如果是字母，则直接返回

            if (ZW.Length == 1)
            {

                return CnChar.ToUpper();

            }

            else
            {

                // get the array of byte from the single char

                int i1 = (short)(ZW[0]);

                int i2 = (short)(ZW[1]);

                iCnChar = i1 * 256 + i2;

            }

            // iCnChar match the constant

            if ((iCnChar >= 45217) && (iCnChar <= 45252))
            {

                return "A";

            }

            else if ((iCnChar >= 45253) && (iCnChar <= 45760))
            {

                return "B";

            }
            else if ((iCnChar >= 45761) && (iCnChar <= 46317))
            {

                return "C";

            }
            else if ((iCnChar >= 46318) && (iCnChar <= 46825))
            {

                return "D";

            }
            else if ((iCnChar >= 46826) && (iCnChar <= 47009))
            {

                return "E";

            }
            else if ((iCnChar >= 47010) && (iCnChar <= 47296))
            {

                return "F";

            }
            else if ((iCnChar >= 47297) && (iCnChar <= 47613))
            {

                return "G";

            }
            else if ((iCnChar >= 47614) && (iCnChar <= 48118))
            {

                return "H";

            }
            else if ((iCnChar >= 48119) && (iCnChar <= 49061))
            {

                return "J";

            }
            else if ((iCnChar >= 49062) && (iCnChar <= 49323))
            {

                return "K";

            }
            else if ((iCnChar >= 49324) && (iCnChar <= 49895))
            {

                return "L";

            }
            else if ((iCnChar >= 49896) && (iCnChar <= 50370))
            {

                return "M";

            }
            else if ((iCnChar >= 50371) && (iCnChar <= 50613))
            {

                return "N";

            }
            else if ((iCnChar >= 50614) && (iCnChar <= 50621))
            {

                return "O";

            }
            else if ((iCnChar >= 50622) && (iCnChar <= 50905))
            {

                return "P";

            }
            else if ((iCnChar >= 50906) && (iCnChar <= 51386))
            {

                return "Q";

            }
            else if ((iCnChar >= 51387) && (iCnChar <= 51445))
            {

                return "R";

            }
            else if ((iCnChar >= 51446) && (iCnChar <= 52217))
            {

                return "S";

            }
            else if ((iCnChar >= 52218) && (iCnChar <= 52697))
            {

                return "T";

            }
            else if ((iCnChar >= 52698) && (iCnChar <= 52979))
            {

                return "W";

            }
            else if ((iCnChar >= 52980) && (iCnChar <= 53640))
            {

                return "X";

            }
            else if ((iCnChar >= 53689) && (iCnChar <= 54480))
            {

                return "Y";

            }
            else if ((iCnChar >= 54481) && (iCnChar <= 55289))
            {

                return "Z";

            }
            else

                return string.Empty;

        }



    }
}
